package br.ufc.great.dtx.dm;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

import ru.ispras.sedna.driver.DatabaseManager;
import ru.ispras.sedna.driver.DriverException;
import ru.ispras.sedna.driver.SednaConnection;
import ru.ispras.sedna.driver.SednaSerializedResult;
import ru.ispras.sedna.driver.SednaStatement;
import br.ufc.great.dtx.server.DTXOutput;
import br.ufc.great.xml.XMLDocument;

/**
 * 
 * @author Leonardo Oliveira Moreira
 *
 * Serviço que controla a persistência e o carregamento dos dados XML para SGBD Sedna XML
 */
public final class DataManagerSednaImpl extends DataManager {
	
	private SednaConnection connection = null;
	
	public DataManagerSednaImpl(DTXOutput output) {
		super(output);
	}
	
	public void close() {
		try {
			connection.close();
		}
		catch (DriverException e) {
			connection = null;
			System.gc();
		}
	}

	public boolean connect(String dataBase, String url, String user, String password) throws IOException {
		boolean result = false;
		try {  
			connection = DatabaseManager.getConnection(url, dataBase, user, password);
			result = true;
		}
		catch (DriverException e) {
			throw new IOException(e);
		}
		return result;
	}

	public boolean updateDocument(String name, XMLDocument document) throws IOException {
		String directory =  System.getProperty("user.dir") + System.getProperty("file.separator") + "tmp" + System.getProperty("file.separator");
		FileWriter fileWriter = new FileWriter(directory + name);
		fileWriter.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>" + document.toString());
		fileWriter.close();
		try {  
			connection.begin();  
			SednaStatement st = connection.createStatement();
			st.execute("DROP DOCUMENT (\"" + name + "\")");
			st = connection.createStatement();
			File file = new File(directory + name);
			FileInputStream fileInputStream = new FileInputStream(file);
			st.loadDocument(fileInputStream, name);
			fileInputStream.close();
			connection.commit();
		}  
		catch (DriverException e) {  
			throw new IOException(e);
		}
		File file = new File(directory + name);
		if (file.exists())
			file.delete();
		return true;
	}

	public XMLDocument loadDocument(String documentName) throws IOException {
		XMLDocument document = null;
		String strDocument = "";
		try {  
			connection.begin();  
			SednaStatement st = connection.createStatement();
			boolean result = st.execute("document(\"" + documentName + "\")");
			if (result) {
				SednaSerializedResult ssr = st.getSerializedResult();
				String item = null;  
				item = ssr.next();
				while (item != null) {  
					strDocument += item;
					item = ssr.next();
				}
			}
			connection.commit();
		}  
		catch (DriverException e) {  
			throw new IOException(e);
		}
		output.print(getClass().getSimpleName(), "Document (" + documentName + ") recovery in the Sedna Database", DTXOutput.MESSAGE);
		document = stringToDocument(documentName, strDocument);
		output.print(getClass().getSimpleName(), "Structure of Document (" + documentName + ") created", DTXOutput.MESSAGE);
		return document;
	}

	public void start(String dataBase) throws IOException {
		try {
			Runtime runtime = Runtime.getRuntime();
			Process process = runtime.exec("se_gov");
			process.waitFor();
			BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			String buffer = null;
			String strResult = "";
			while ((buffer = reader.readLine()) != null)
				strResult += buffer;
			if (strResult.trim().length() == 0)
				strResult = "GOVERNOR has been started in the background mode";
			output.print(getClass().getSimpleName(), strResult, DTXOutput.MESSAGE);
			process = runtime.exec("se_sm " + dataBase);
			process.waitFor();
			reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			buffer = null;
			strResult = "";
			while ((buffer = reader.readLine()) != null)
				strResult += buffer;
			if (strResult.trim().length() == 0)
				strResult = "SM has been started in the background mode";
			output.print(getClass().getSimpleName(), strResult, DTXOutput.MESSAGE);
		}
		catch (InterruptedException e) {
			throw new IOException(e);
		}
	}

	public void stop(String dataBase) throws IOException {
		try {
			Runtime runtime = Runtime.getRuntime();
			Process process = runtime.exec("se_smsd " + dataBase);
			process.waitFor();
			BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			String buffer = null;
			String strResult = "";
			while ((buffer = reader.readLine()) != null)
				strResult += buffer;
			output.print(getClass().getSimpleName(), strResult, DTXOutput.MESSAGE);
			process = runtime.exec("se_stop");
			process.waitFor();
			reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			buffer = null;
			strResult = "";
			while ((buffer = reader.readLine()) != null)
				strResult += buffer;
			output.print(getClass().getSimpleName(), strResult, DTXOutput.MESSAGE);
		}
		catch (InterruptedException e) {
			throw new IOException(e);
		}
	}
}
